Лабораторная работа №12 "Блок приоритетных прерываний"
В базовом варианте лабораторных работ предлагается реализовать процессорную систему с одним источником прерываний, чего достаточно для выполнения лабораторных работ. Однако, если появится желание усовершенствовать систему и увеличить количество периферийных устройств, то поддержка только одного источника прерываний создаст множество сложностей. В рамках данной лабораторной работы необходимо реализовать блок приоритетных прерываний и интегрировать его в контроллер прерываний, увеличив число потенциальных источников прерываний до 16.
Цель
- Разработать блок приоритетных прерываний (БПП), построенный по схеме daisy chain.
- Интегрировать БПП в контроллер прерываний.
Теория
Если процессорная система предполагает наличие более одного источника прерываний, то необходимо разобраться с тем, что делать в случае возникновения коллизий — наложения одновременных запросов прерываний от нескольких источников. Одним из способов решения такой проблемы является реализация приоритетов прерываний. Со схемотехнической точки зрения, проще всего реализовать схему со статическим, не изменяемым, приоритетом. Одной из таких схем является daisy chain (по-русски — гирлянда, или дейзи-чейн, или дейзи-цепочка). Пример такой схемы можно увидеть на рис. 1.
Рисунок 1. Структурная схема daisy chain.
Данная схема состоит из двух массивов элементов И. Первый массив (верхний ряд элементов) формирует многоразрядный сигнал (назовём его для определённости ready
, на рис. 1 он обозначен как "Приоритет"), который перемножается с запросами с помощью массива элементов И нижнего ряда, формируя многоразрядный сигнал y
. Обратите внимание на то, что результат операции И на очередном элементе нижнего массива влияет на результат И следующего за ним элемента верхнего массива и наоборот (readyₙ₊₁
зависит от yₙ
, в то время как yₙ
зависит от readyₙ
). Как только на одном из разрядов y
появится значение 1
, оно сразу же распространится в виде 0
по всем оставшимся последующим разрядам ready
, обнуляя их. А приняв нулевое значение, разряды ready
обнулят соответствующие разряды y
(нулевые разряды ready
запрещают генерацию прерывания для соответствующих разрядов y
).
Нижний массив элементов И можно описать через непрерывное присваивание побитового И между ready
и сигналом запросов на прерывание.
Для описания верхнего ряда элементов И вам будет необходимо сделать непрерывное присваивание readyₙ & !yₙ
для n+1
-ого бита ready
. Для этого будет удобно воспользоваться конструкцией generate for
, которая позволяет автоматизировать создание множества однотипных структур.
Рассмотрим принцип работы этой конструкции. Предположим, мы хотим создать побитовое присваивание 5-битного сигнала a
5-битному сигналу b
.
Индексы, используемые конструкцией, должны быть объявлены с помощью ключевого слова genvar
. Далее, в области, ограниченной ключевыми словами generate
/endgenerate
описывается цикл присваиваний (в подобном цикле можно и создавать модули):
logic [4:0] a;
logic [4:0] b;
// ...
genvar i;
generate
for(i = 0; i < 5; i++) begin
assign a[i] = b[i];
end
endgenerate
Листинг 1. Пример использования конструкции generate.
Разумеется в этом примере можно было бы просто сделать одно непрерывное присваивание assign a = b;
, однако в случае реализации верхнего ряда элементов И, подобное многобитное непрерывное присваивание не приведёт к синтезу требуемой схемы.
Практика
Рассмотрим реализацию контроллера прерываний, представленную на рис. 2.
Рисунок 2. Структурная схема блока приоритетных прерываний.
Помимо портов clk_i
и rst_i
, модуль daisy_chain
будет иметь 3 входа и три выхода:
masked_irq_i
— 16-разрядный вход маскированного запроса на прерывания (т.е. источник прерывания уже прошел маскирование сигналом регистра контроля и статусаmie
).irq_ret_i
— сигнал о возврате управления основному потоку инструкций (выход из обработчика прерываний).ready_i
— сигнал о готовности процессора к перехвату (т.е. прямо сейчас процессор не находится в обработчике перехвата). Это нулевой бит сигналаready
в дейзи-цепочке. Покаready_i
равен нулю, дейзи-цепочка не будет генерировать сигналы прерываний.irq_o
— сигнал о начале обработки прерываний.irq_cause_o
— причина прерывания.irq_ret_o
— сигнал о завершении обработки запроса на прерывания. Будет соответствоватьcause_o
в момент появления сигналаmret_i
.
Внутренний сигнал cause
является сигналом y
с рис. 1. Как пояснялось выше, этот сигнал может содержать только одну единицу, она будет соответствовать прошедшему запросу на прерывание. А значит этот результат можно использовать в качестве сигнала для идентификации причины прерывания. При этом, свертка по ИЛИ (операция ИЛИ между всеми битами) этого сигнала даст итоговый запрос на прерывание.
Однако, как упоминалось в ЛР№10, спецификация RISC-V накладывает определенные требования на кодирование кода mcause
для причины прерывания. В частности, необходимо выставить старший бит в единицу, а значение на оставшихся битах должно быть больше 16. Схемотехнически это проще реализовать выполнив склейку {12'h800, cause, 4'b0000}
— в этом случае старший разряд будет равен единице, и если хоть один разряд cause
будет равен единице (а именно это и является критерием появления прерывания), младшие 31 бит mcause
будут больше 16.
Регистр на рис. 2 хранит значение внутреннего сигнала cause
, чтобы по завершению прерывания выставить единицу на соответствующем разряде сигнала irq_ret_o
, который сообщит устройству, чьё прерывание обрабатывалось ранее, что его обработка завершена.
Задание
- Реализовать модуль
daisy_chain
. - Интегрировать
daisy_chain
в модульirq_controller
по схеме, представленной на рис. 3. - Отразить изменения в прототипе сигнала
irq_controller
в модуляхriscv_core
иriscv_unit
.
Рисунок 3. Структурная схема блока приоритетных прерываний.
Обратите внимание, что разрядность сигналов irq_req_i
, mie_i
, irq_ret_o
изменилась. Теперь это 16-разрядные сигналы. Сигнал, который ранее шёл на выход к irq_ret_o
теперь идёт на вход irq_ret_i
модуля daisy_chain
. Формирование кода причины прерывания irq_cause_o
перенесено в модуль daisy_chain
.
Порядок выполнения работы
- Опишите модуль
daisy_chain
.- При формировании верхнего массива элементов И с рис. 2, вам необходимо воспользоваться сформировать 16 непрерывных присваиваний через блок
generate for
. - Формирование нижнего массива элементов И можно сделать с помощью одного непрерывного присваивания посредством операции побитовое И.
- При формировании верхнего массива элементов И с рис. 2, вам необходимо воспользоваться сформировать 16 непрерывных присваиваний через блок
- Проверьте модуль
daisy_chain
с помощью верификационного окружения, представленного в файлеlab_12.tb_daisy_chain
. В случае, если в TCL-консоли появились сообщения об ошибках, вам необходимо найти и исправить их.- Перед запуском моделирования, убедитесь, что у вас выбран корректный модуль верхнего уровня в
Simulation Sources
.
- Перед запуском моделирования, убедитесь, что у вас выбран корректный модуль верхнего уровня в
- Интегрируйте модуль
daisy_chain
в модульirq_controller
по схеме, представленной на рис. 3.- Не забудьте обновить разрядность сигналов
irq_req_i
,mie_i
,irq_ret_o
в модулеirq_controller
. - Также не забудьте обновить разрядность сигналов
irq_req_i
,irq_ret_o
в модуляхprocessor_core
иprocessor_system
. - Кроме того, теперь вам нужно использовать старшие 16 бит сигнала
mie
вместо одного при подключении модуляirq_controller
в модулеprocessor_core
.
- Не забудьте обновить разрядность сигналов
- Проверьте с помощью верификационного окружения из ЛР№11, что в процессе интеграции ничего не сломалось.